package org.light.oracle.oracleverb;

import java.util.ArrayList;
import java.util.List;

import org.light.core.Verb;
import org.light.core.Writeable;
import org.light.domain.Domain;
import org.light.domain.Dropdown;
import org.light.domain.Field;
import org.light.domain.JavascriptBlock;
import org.light.domain.JavascriptMethod;
import org.light.domain.Method;
import org.light.domain.Signature;
import org.light.domain.Statement;
import org.light.domain.StatementList;
import org.light.domain.Type;
import org.light.easyui.EasyUIPositions;
import org.light.exception.ValidateException;
import org.light.utils.StringUtil;
import org.light.utils.WriteableUtil;
import org.light.verb.SearchByFields;

public class FilterPDF extends Verb implements EasyUIPositions {
	protected SearchByFields search = new SearchByFields();

	@Override
	public Method generateDaoImplMethod() throws Exception {
		return null;
	}

	@Override
	public String generateDaoImplMethodString() throws Exception {
		return null;
	}

	@Override
	public Method generateDaoMethodDefinition() throws Exception {
		return null;
	}

	@Override
	public String generateDaoMethodDefinitionString() throws Exception {
		return null;
	}

	@Override
	public String generateDaoImplMethodStringWithSerial() throws Exception {
		return null;
	}

	@Override
	public Method generateServiceMethodDefinition() throws Exception {
		return null;
	}

	@Override
	public String generateServiceMethodDefinitionString() throws Exception {
		return null;
	}

	@Override
	public Method generateServiceImplMethod() throws Exception {
		return null;
	}

	@Override
	public String generateServiceImplMethodString() throws Exception {
		return null;
	}

	@Override
	public String generateServiceImplMethodStringWithSerial() throws Exception {
		return null;
	}

	public FilterPDF() {
		super();
		this.setLabel("PDF过滤");
	}

	public FilterPDF(Domain domain) throws ValidateException{
		super();
		this.domain = domain;
		this.denied = domain.isVerbDenied("FilterPDF");
		this.search = new SearchByFields(domain);
		this.setVerbName("filter" + StringUtil.capFirst(this.domain.getPlural()) + "PDF");
		this.setLabel("PDF过滤");
		if  (domain.getLanguage().equalsIgnoreCase("english"))  this.setLabel("FilterPDF");
	}

	@Override
	public Method generateControllerMethod() throws Exception {
		if (this.denied)
			return null;
		else {
			this.search.setDomain(this.domain);

			Method method = new Method();
			method.setStandardName("filter" + StringUtil.capFirst(this.domain.getPlural()) + "PDF");
			method.setReturnType(new Type("void"));
			method.setThrowException(true);
			method.addAdditionalImport(this.domain.getPackageToken() + ".utils.PDFUtil");
			method.addAdditionalImport("java.io.OutputStream");
			method.addAdditionalImport("java.util.Arrays");
			method.addAdditionalImport("java.util.ArrayList");
			method.addAdditionalImport("java.util.List");
			method.addAdditionalImport("javax.servlet.http.HttpServletRequest");
			method.addAdditionalImport("javax.servlet.http.HttpServletResponse");
			method.addAdditionalImport("javax.servlet.http.HttpSession");
			method.addAdditionalImport(this.domain.getPackageToken() + ".utils.BooleanUtil");
			method.addAdditionalImport(this.domain.getPackageToken()+".utils.StringUtil");
			method.addAdditionalImport(this.domain.getPackageToken() + "." + this.domain.getDomainSuffix() + "."
					+ this.domain.getCapFirstDomainNameWithSuffix());
			method.addAdditionalImport(this.domain.getPackageToken() + "." + this.domain.getServiceSuffix() + "."
					+ this.domain.getStandardName() + "Service");

			method.addSignature(new Signature(1, "session", new Type("HttpSession")));
			method.addSignature(new Signature(2, "response", new Type("HttpServletResponse")));
			method.addSignature(new Signature(3, "request", new Type("HttpServletRequest")));

			int sigPos = 4;
			for (Field f : this.domain.getSearchFields()) {
				if (f.getFieldType().equalsIgnoreCase("Boolean")) {
					method.addSignature(new Signature(sigPos, f.getLowerFirstFieldName(), new Type("String"), "",
							"RequestParam(value = \"" + f.getLowerFirstFieldName() + "\", required = false)"));
				} else {
					method.addSignature(new Signature(sigPos, f.getLowerFirstFieldName(), f.getClassType(), "",
							"RequestParam(value = \"" + f.getLowerFirstFieldName() + "\", required = false)"));
				}
				sigPos++;
			}
			method.addMetaData("RequestMapping(value = \"/" + StringUtil.lowerFirst(method.getStandardName())
					+ "\", method = RequestMethod.GET)");

			List<Writeable> sList = new ArrayList<Writeable>();
			sList.add(new Statement(1000L, 2,
					this.domain.getCapFirstDomainNameWithSuffix() + " " + this.domain.getLowerFirstDomainName()
							+ "0 = new " + this.domain.getCapFirstDomainNameWithSuffix() + "();"));

			long serial = 2000L;
			for (Field f : this.domain.getSearchFields()) {
				if (f.getFieldType().equalsIgnoreCase("Boolean")) {
					sList.add(new Statement(serial, 2, "Boolean " + f.getLowerFirstFieldName()
							+ "Bool = BooleanUtil.parseBoolean(" + f.getLowerFirstFieldName() + ");"));
					sList.add(new Statement(serial + 500L, 2,
							"if (" + f.getLowerFirstFieldName() + "Bool != null) "
									+ this.domain.getLowerFirstDomainName() + "0." + f.getSetterCallName() + "("
									+ f.getLowerFirstFieldName() + "Bool);"));
				}  else if (f.getFieldType().equalsIgnoreCase("String") ){
					sList.add(new Statement(serial, 2,
							"if (!StringUtil.isBlank(" + f.getLowerFirstFieldName() + ")) " + this.domain.getLowerFirstDomainName()
									+ "0." + f.getSetterCallName() + "(" + f.getLowerFirstFieldName() + ");"));
				} else {
					sList.add(new Statement(serial, 2,
							"if (" + f.getLowerFirstFieldName() + " != null) " + this.domain.getLowerFirstDomainName()
									+ "0." + f.getSetterCallName() + "(" + f.getLowerFirstFieldName() + ");"));
				}
				serial += 1000L;
			}

			sList.add(new Statement(serial + 1000L, 2, "try(OutputStream out = response.getOutputStream()){"));
			sList.add(new Statement(serial + 2000L, 3,
					"response.addHeader(\"Content-Disposition\", \"attachment;filename="
							+ this.domain.getCapFirstPlural() + ".pdf\");"));
			sList.add(new Statement(serial + 3000L, 3,
					"List<" + this.domain.getCapFirstDomainNameWithSuffix() + "> list = service.search"
							+ this.domain.getCapFirstPlural() + "ByFields(" + this.domain.getLowerFirstDomainName()
							+ "0);"));
			sList.add(new Statement(serial + 4000L, 3, "List<List<Object>> contents = new ArrayList<>();"));
			if  (domain.getLanguage().equalsIgnoreCase("english"))  {
				sList.add(new Statement(serial + 5000L,3,"String sheetName = \""+this.domain.getText()+" Information\";"));
			}else {
				sList.add(new Statement(serial + 5000L,3,"String sheetName = \""+this.domain.getText()+"信息表\";"));			
			}
			sList.add(new Statement(serial + 6000L, 3,
					"String [] headers = " + this.domain.generateFieldLabelsArrayStr(this.domain.getFields()) + ";"));
			sList.add(new Statement(serial+6500L,3,"Boolean [] isImages = "+this.domain.generateIsImageFieldsArrayStr(this.domain.getFields())+";"));
			sList.add(new Statement(serial + 7000L, 3, ""));
			sList.add(new Statement(serial + 8000L, 3, "for (" + this.domain.getCapFirstDomainNameWithSuffix() + " "
					+ this.domain.getLowerFirstDomainName() + ":list) {"));
			serial += 9000L;
			for (Field f : this.domain.getFields()) {
				if (f instanceof Dropdown) {
					Dropdown dp = (Dropdown) f;
					sList.add(new Statement(serial, 4, f.getFieldType() + " " + f.getLowerFirstFieldName() + "0 = "
							+ this.domain.getLowerFirstDomainName() + ".get" + f.getCapFirstFieldName() + "();"));
					sList.add(new Statement(serial + 500L, 4,
							dp.getTarget().getType() + " " + dp.getAliasName() + "Type0;"));
					sList.add(new Statement(serial + 1000L, 4,
							dp.getTarget().getDomainName().getFieldType() + " " + dp.getAliasName() + "Name0 = \"\";"));
					sList.add(new Statement(serial + 2000L, 4, "if (" + f.getLowerFirstFieldName() + "0 != null) {"));
					sList.add(new Statement(serial + 2100L, 5,
							dp.getAliasName() + "Type0 = " + StringUtil.lowerFirst(dp.getTargetName()) + "Service.find"
									+ dp.getTarget().getCapFirstDomainName() + "By"
									+ dp.getTarget().getDomainId().getCapFirstFieldName() + "("
									+ f.getLowerFirstFieldName() + "0);"));
					sList.add(new Statement(serial + 2200L, 5,
							"if (" + dp.getAliasName() + "Type0 !=null) " + dp.getAliasName() + "Name0 = "
									+ dp.getAliasName() + "Type0.get"
									+ dp.getTarget().getDomainName().getCapFirstFieldName() + "();"));
					sList.add(new Statement(serial + 2300L, 4, "}"));
					serial += 3000L;
				}
			}
			String sc = "Object [] row = {";
			for (Field f : this.domain.getFields()) {
				if (f instanceof Dropdown) {
					Dropdown dp = (Dropdown) f;
					sc += dp.getAliasName() + "Name0,";
				} else {
					if (f.getFieldType().equalsIgnoreCase("String")||f.getFieldType().equalsIgnoreCase("image")) {
						sc += this.domain.getLowerFirstDomainName() + ".get" + f.getCapFirstFieldName() + "(),";
					} else {
						sc += "StringUtil.toNullString("+this.domain.getLowerFirstDomainName()+".get"+f.getCapFirstFieldName()+"()),";
					}
				}
			}
			if (this.domain.getFields() != null && this.domain.getFields().size() > 0) {
				sc = sc.substring(0, sc.length() - 1);
			}
			sc += "};";
			sList.add(new Statement(serial, 4, sc));
			sList.add(new Statement(serial + 1000L, 4, "contents.add(Arrays.asList(row));"));
			sList.add(new Statement(serial + 2000L, 3, "}"));
			sList.add(new Statement(serial + 3000L, 3, ""));
			sList.add(new Statement(serial + 4000L, 3,
					"PDFUtil.exportPDFWithImage(out, sheetName, Arrays.asList(headers), contents, Arrays.asList(isImages));"));
			sList.add(new Statement(serial + 5000L, 2, "}"));
			method.setMethodStatementList(WriteableUtil.merge(sList));

			return method;
		}
	}

	@Override
	public String generateControllerMethodString() throws Exception {
		if (this.denied)
			return null;
		else {
			Method m = this.generateControllerMethod();
			return m.generateMethodString();
		}
	}

	@Override
	public String generateControllerMethodStringWithSerial() throws Exception {
		if (this.denied)
			return null;
		else {
			Method m = this.generateControllerMethod();
			m.setContent(m.generateMethodContentStringWithSerial());
			m.setMethodStatementList(null);
			return m.generateMethodString();
		}
	}

	@Override
	public JavascriptBlock generateEasyUIJSButtonBlock() throws Exception {
		return null;
	}

	@Override
	public String generateEasyUIJSButtonBlockString() throws Exception {
		return null;
	}

	@Override
	public String generateEasyUIJSButtonBlockStringWithSerial() throws Exception {
		return null;
	}

	@Override
	public JavascriptMethod generateEasyUIJSActionMethod() throws Exception {
		if (this.denied)
			return null;
		else {
			Domain domain = this.domain;
			JavascriptMethod method = new JavascriptMethod();
			method.setSerial(200);
			method.setStandardName("filter" + domain.getPlural() + "PDF");

			StatementList sl = new StatementList();
			sl.add(new Statement(1000, 1, "params = {"));
			long serial = 2000;
			for (Field f : domain.getSearchFields()) {
				if (f instanceof Dropdown)
					sl.add(new Statement(serial, 2, f.getLowerFirstFieldName() + ":$(\"#ffsearch\").find(\"#"
							+ f.getLowerFirstFieldName() + "\").combobox(\"getValue\"),"));
				else if (!f.getFieldType().equalsIgnoreCase("boolean"))
					sl.add(new Statement(serial, 2, f.getLowerFirstFieldName() + ":$(\"#ffsearch\").find(\"#"
							+ f.getLowerFirstFieldName() + "\").val(),"));
				else
					sl.add(new Statement(serial, 2, f.getLowerFirstFieldName()
							+ ":parseBoolean($(\"#ffsearch\").find(\"#" + f.getLowerFirstFieldName() + "\").val()),"));
				serial += 1000;
			}
			sl.add(new Statement(serial, 1, "};"));
			sl.add(new Statement(serial + 1000, 1, "var params0 = $.param(params);"));
			sl.add(new Statement(serial + 2000, 1,
					"document.location.href = \"../"+this.domain.getControllerPackagePrefix() + this.domain.getLowerFirstDomainName()
							+ domain.getControllerNamingSuffix() + "/filter" + this.domain.getCapFirstPlural()
							+ "PDF?\" + params0;"));

			method.setMethodStatementList(sl);
			return method;
		}
	}

	@Override
	public String generateEasyUIJSActionString() throws Exception {
		if (this.denied)
			return null;
		else {
			return generateEasyUIJSActionMethod().generateMethodString();
		}
	}

	@Override
	public String generateEasyUIJSActionStringWithSerial() throws Exception {
		if (this.denied)
			return null;
		else {
			return generateEasyUIJSActionMethod().generateMethodString();
		}
	}

}
